/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.progin.drop.server;

import com.progin.drop.core.Message;
import com.progin.drop.core.MessageException;
import com.progin.drop.core.MessageOperator;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author HP
 */
public class Worker implements Runnable {
    private Socket mSock;
    private Message mMessage;

    public Worker(Socket sock) {
        mSock = sock;
    }

    public void run() {
        try {
            MessageOperator mo = new MessageOperator();
            mMessage = mo.receive(mSock);
            System.out.println("Receiving message : " + mMessage);

            //Handler h = new Handler(mSock);
            //h.handleMessage(mMessage);
            handleMessage(mo);
            mSock.close();
        } catch (MessageException ex) {
            Logger.getLogger(Worker.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
        } catch (IOException ex) {
            Logger.getLogger(Worker.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
        }
    }

    public void handleMessage(MessageOperator operator) {
        try {
            Message message = operator.getTargetMessage();
            int id = message.getId();
            Message response = null;

            switch (id) {
                case Message.MESSAGE_LIST_FILES:
                    response = listFiles(message.getHeader(1));
                    break;
                case Message.MESSAGE_REQUEST_FILE:
                    response = requestFile(message.getHeader(1), message.getBody(0) , message.getmBodies().size() >= 2 && message.getBody(1).equals("delete"));
                    break;
                case Message.MESSAGE_SEND_FILE:
                    response = sendFile(operator);
                    break;
            }

            if (response != null) {
                MessageOperator mo = new MessageOperator(response);
                try {
                    mo.send(mSock);
                } catch (MessageException ex) {
                    Logger.getLogger(Handler.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
                }
            }
        } catch (MessageException ex) {
            Logger.getLogger(Handler.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage(), ex);
        }
    }

    //public Message sendFile(String userid , String filename , byte[] stream) {
    public Message sendFile(MessageOperator operator) throws MessageException {
        Message msg = operator.getTargetMessage();
        String userid = msg.getHeader(1);
        String filename = msg.getBody(0);

        File pastFile = new File(Main.basedir + "/" + userid + "/" + filename + ".del");
        if (pastFile.exists())
            pastFile.delete();

        File targetFile = new File(Main.basedir + "/" + userid + "/" + filename);
        StreamHandler handler = new StreamHandler(targetFile);
        operator.setHandler(handler);
        operator.loadAttachment(mSock);
        
        return null;
    }

    public Message requestFile(String userid , String filename , boolean isDelete) {
        Message response = null;

        File targetFile = new File(Main.basedir + "/" + userid + "/" + filename);
        //System.out.println(targetFile);
        if (targetFile.exists() && targetFile.isFile()) {
            if (!isDelete) {
                try {
                    FileInputStream fis = new FileInputStream(targetFile);

                    //byte[] b = new byte[(int)targetFile.length()];
                    //fis.read(b);

                    response = new Message(Message.MESSAGE_SEND_FILE , targetFile);
                    response.getmHeaders().add(userid);
                    response.getmHeaders().add("0");

                    response.getmBodies().add(targetFile.getName());
                    //response.setByteStream(b);
                    System.out.println(response.getAttachmentLength());

                    fis.close();
                } catch (IOException ex) {
                    Logger.getLogger(Handler.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
                }
            }
            else {
                targetFile.renameTo(new File(targetFile.getAbsolutePath() + ".del"));
                //targetFile.delete();
                response = new Message(Message.MESSAGE_REQUEST_FILE , null);
                response.getmHeaders().add(userid);
                response.getmHeaders().add("0");
                response.getmBodies().add(targetFile.getName());
            }
        }
        else {
            response = new Message(Message.MESSAGE_SEND_FILE , null);
            response.getmHeaders().add(userid);
            response.getmHeaders().add("1");
        }

        return response;
    }

    public Message listFiles(String userid) {
        File repo = new File(Main.basedir + "/" + userid);
        File[] files = repo.listFiles();

        Message response = new Message(Message.MESSAGE_LIST_FILES , null);
        response.getmHeaders().add(userid);
        for (File f : files) {
            String filedesc = "";

            if (f.getName().contains(".del")) {
                filedesc += f.getName().replace(".del", "") + "," + Util.getFileChecksum(f) + "," + f.length() + "," + f.lastModified();
                filedesc += ",deleted";
            }
            else {
                filedesc += f.getName() + "," + Util.getFileChecksum(f) + "," + f.length() + "," + f.lastModified();
            }
            response.getmBodies().add(filedesc);
        }
        return response;
    }

}
